home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / terms / tipx / libacu / ventel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-11  |  4.8 KB  |  235 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)ventel.c    5.2 (Berkeley) 9/13/88";
  20. #endif /* not lint */
  21.  
  22. /*
  23.  * Routines for calling up on a Ventel Modem
  24.  * The Ventel is expected to be strapped for local echo (just like uucp)
  25.  */
  26. #include "tip.h"
  27.  
  28. #define    MAXRETRY    5
  29.  
  30. static    int sigALRM();
  31. static    int timeout = 0;
  32. static    jmp_buf timeoutbuf;
  33.  
  34. /*
  35.  * some sleep calls have been replaced by this macro
  36.  * because some ventel modems require two <cr>s in less than
  37.  * a second in order to 'wake up'... yes, it is dirty...
  38.  */
  39. #define delay(num,denom) busyloop(CPUSPEED*num/denom)
  40. #define CPUSPEED 1000000    /* VAX 780 is 1MIPS */
  41. #define    DELAY(n)    { register long N = (n); while (--N > 0); }
  42. busyloop(n) { DELAY(n); }
  43.  
  44. ven_dialer(num, acu)
  45.     register char *num;
  46.     char *acu;
  47. {
  48.     register char *cp;
  49.     register int connected = 0;
  50.     char *msg, *index(), line[80];
  51.  
  52.     /*
  53.      * Get in synch with a couple of carriage returns
  54.      */
  55.     if (!vensync(FD)) {
  56.         printf("can't synchronize with ventel\n");
  57. #ifdef ACULOG
  58.         logent(value(HOST), num, "ventel", "can't synch up");
  59. #endif
  60.         return (0);
  61.     }
  62.     if (boolean(value(VERBOSE)))
  63.         printf("\ndialing...");
  64.     fflush(stdout);
  65.     ioctl(FD, TIOCHPCL, 0);
  66.     echo("#k$\r$\n$D$I$A$L$:$ ");
  67.     for (cp = num; *cp; cp++) {
  68.         delay(1, 10);
  69.         write(FD, cp, 1);
  70.     }
  71.     delay(1, 10);
  72.     write(FD, "\r", 1);
  73.     gobble('\n', line);
  74.     if (gobble('\n', line))
  75.         connected = gobble('!', line);
  76.     ioctl(FD, TIOCFLUSH);
  77. #ifdef ACULOG
  78.     if (timeout) {
  79.         sprintf(line, "%d second dial timeout",
  80.             number(value(DIALTIMEOUT)));
  81.         logent(value(HOST), num, "ventel", line);
  82.     }
  83. #endif
  84.     if (timeout)
  85.         ven_disconnect();    /* insurance */
  86.     if (connected || timeout || !boolean(value(VERBOSE)))
  87.         return (connected);
  88.     /* call failed, parse response for user */
  89.     cp = index(line, '\r');
  90.     if (cp)
  91.         *cp = '\0';
  92.     for (cp = line; cp = index(cp, ' '); cp++)
  93.         if (cp[1] == ' ')
  94.             break;
  95.     if (cp) {
  96.         while (*cp == ' ')
  97.             cp++;
  98.         msg = cp;
  99.         while (*cp) {
  100.             if (isupper(*cp))
  101.                 *cp = tolower(*cp);
  102.             cp++;
  103.         }
  104.         printf("%s...", msg);
  105.     }
  106.     return (connected);
  107. }
  108.  
  109. ven_disconnect()
  110. {
  111.  
  112.     close(FD);
  113. }
  114.  
  115. ven_abort()
  116. {
  117.  
  118.     write(FD, "\03", 1);
  119.     close(FD);
  120. }
  121.  
  122. static int
  123. echo(s)
  124.     register char *s;
  125. {
  126.     char c;
  127.  
  128.     while (c = *s++) switch (c) {
  129.  
  130.     case '$':
  131.         read(FD, &c, 1);
  132.         s++;
  133.         break;
  134.  
  135.     case '#':
  136.         c = *s++;
  137.         write(FD, &c, 1);
  138.         break;
  139.  
  140.     default:
  141.         write(FD, &c, 1);
  142.         read(FD, &c, 1);
  143.     }
  144. }
  145.  
  146. static int
  147. sigALRM()
  148. {
  149.  
  150.     printf("\07timeout waiting for reply\n");
  151.     timeout = 1;
  152.     longjmp(timeoutbuf, 1);
  153. }
  154.  
  155. static int
  156. gobble(match, response)
  157.     register char match;
  158.     char response[];
  159. {
  160.     register char *cp = response;
  161.     char c;
  162.     int (*f)();
  163.  
  164.     signal(SIGALRM, sigALRM);
  165.     timeout = 0;
  166.     do {
  167.         if (setjmp(timeoutbuf)) {
  168.             signal(SIGALRM, f);
  169.             *cp = '\0';
  170.             return (0);
  171.         }
  172.         alarm(number(value(DIALTIMEOUT)));
  173.         read(FD, cp, 1);
  174.         alarm(0);
  175.         c = (*cp++ &= 0177);
  176. #ifdef notdef
  177.         if (boolean(value(VERBOSE)))
  178.             putchar(c);
  179. #endif
  180.     } while (c != '\n' && c != match);
  181.     signal(SIGALRM, SIG_DFL);
  182.     *cp = '\0';
  183.     return (c == match);
  184. }
  185.  
  186. #define min(a,b)    ((a)>(b)?(b):(a))
  187. /*
  188.  * This convoluted piece of code attempts to get
  189.  * the ventel in sync.  If you don't have FIONREAD
  190.  * there are gory ways to simulate this.
  191.  */
  192. static int
  193. vensync(fd)
  194. {
  195.     int already = 0, nread;
  196.     char buf[60];
  197.  
  198.     /*
  199.      * Toggle DTR to force anyone off that might have left
  200.      * the modem connected, and insure a consistent state
  201.      * to start from.
  202.      *
  203.      * If you don't have the ioctl calls to diddle directly
  204.      * with DTR, you can always try setting the baud rate to 0.
  205.      */
  206.     ioctl(FD, TIOCCDTR, 0);
  207.     sleep(1);
  208.     ioctl(FD, TIOCSDTR, 0);
  209.     while (already < MAXRETRY) {
  210.         /*
  211.          * After reseting the modem, send it two \r's to
  212.          * autobaud on. Make sure to delay between them
  213.          * so the modem can frame the incoming characters.
  214.          */
  215.         write(fd, "\r", 1);
  216.         delay(1,10);
  217.         write(fd, "\r", 1);
  218.         sleep(2);
  219.         if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
  220.             perror("tip: ioctl");
  221.             continue;
  222.         }
  223.         while (nread > 0) {
  224.             read(fd, buf, min(nread, 60));
  225.             if ((buf[nread - 1] & 0177) == '$')
  226.                 return (1);
  227.             nread -= min(nread, 60);
  228.         }
  229.         sleep(1);
  230.         already++;
  231.     }
  232.     return (0);
  233. }
  234.  
  235.